import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.common.base.BaseController;
import com.common.base.BaseEntity;
import com.common.base.BaseServiceImpl;
import com.common.base.IBaseService;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * <p>
 * MyBatis Plus Generator 配置执行类示例
 *
 * Field 备注,table是否显示,search条件是否生成,edit.ftl是否生成,edit.ftl是否显示,edit.ftl下拉框,mapper启用like模糊搜索
 * </p>
 *
 * @author XiaoPengwei.com
 * @since 2019-04-07
 */
public class OkmServerGenerator {

    //        private static final String entity = "/okm/entity.java";
    private static final String entityKt = "/okm/entity.kt";
    private static final String service = "/okm/service.java";
    private static final String serviceImpl = "/okm/serviceImpl.java";

    private static final String mapper = "/okm/mapper.java.ftl";
    private static final String controller = "/okm/controller.kt.ftl";

    private static final String xml = "/okm/mapper.xml.ftl";
    private static final String viewList = "/okm/view.list.ftl";
    private static final String viewEdit = "/okm/view.edit.ftl";
    private static final String viewDetail = "/okm/view.detail.ftl";

    private static final String basePath = "D:\\workspace\\okm.server\\";

//    private static final String serviceInterfacePkg = ".service";
//    private static final String serviceImplPkg = ".service.impl";

    private static final String jdbcUrl = "jdbc:mysql://139.196.206.242:3306/tenant_lgl?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai";
    private static final String username = "root";
    private static final String password = "lgl123";
//    private static final String jdbcUrl = "jdbc:mysql://192.168.1.6:3306/tenant_lgl?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai";
//    private static final String username = "root";
//    private static final String password = "root";

    // order-instant
//    private static final String pkg = "com.lgl.order.instant";
//
//    private static final String viewPath = basePath + "lgl-erp\\src\\main\\webapp\\WEB-INF\\view\\";
//    private static final String controllerPath = basePath + "\\lgl-erp\\src\\main\\java\\com\\lgl\\erp\\controller\\instant\\";
//
//    private static final String projectPath = basePath + "order\\order-instant";
//    private static final String mapperPath = projectPath + "\\src\\main\\java\\com\\lgl\\db\\mapper\\instant\\";
//    private static final String mapperXmlPath = projectPath + "\\src\\main\\resources\\com\\lgl\\db\\mapper\\instant\\";

    private static final String serviceInterfacePkg = ".service";
    private static final String serviceImplPkg = ".service.impl";

//    // order-third
    private static final String pkg = "com.lgl.order.third";
    private static final String pkgMapper = "com.lgl.db.mapper.third";
    private static final String pkgController = "com.lgl.erp.controller.third";

    private static final String viewPath = basePath + "lgl-erp\\src\\main\\webapp\\WEB-INF\\view\\";
    private static final String controllerPath = basePath + "\\lgl-erp\\src\\main\\java\\com\\lgl\\erp\\controller\\third\\";

    private static final String projectPath = basePath + "order\\order-third";
    private static final String mapperPath = projectPath + "\\src\\main\\java\\com\\lgl\\db\\mapper\\third\\";
    private static final String mapperXmlPath = projectPath + "\\src\\main\\resources\\com\\lgl\\db\\mapper\\third\\";

    // notify
//    private static final String pkg = "com.lgl.notify";
//    private static final String pkgMapper = "com.lgl.db.mapper.notify";
//    private static final String pkgController = "com.lgl.erp.controller.basic";
//
//    private static final String viewPath = basePath + "lgl-erp\\src\\main\\webapp\\WEB-INF\\view\\";
//    private static final String controllerPath = basePath + "\\lgl-erp\\src\\main\\java\\com\\lgl\\erp\\controller\\basic\\";
//
//    private static final String projectPath = basePath + "notify";
//    private static final String mapperPath = projectPath + "\\src\\main\\java\\com\\lgl\\db\\mapper\\notify\\";
//    private static final String mapperXmlPath = projectPath + "\\src\\main\\resources\\com\\lgl\\db\\mapper\\notify\\";

//    private static final String serviceInterfacePkg = ".service.interfaces";
//    private static final String serviceImplPkg = ".service";

    // base_share
//    private static final String jdbcUrl = "jdbc:mysql://192.168.1.6:3306/base_share?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai";
//    private static final String username = "root";
//    private static final String password = "root";
//
//    private static final String pkg = "com.lgl.bean.basic";
//    private static final String pkgMapper = "com.lgl.db.mapper.basic";
//    private static final String pkgController = "com.lgl.erp.controller.basic";
//
//    private static final String viewPath = basePath + "lgl-erp\\src\\main\\webapp\\WEB-INF\\view\\";
//    private static final String controllerPath = basePath + "\\lgl-erp\\src\\main\\java\\com\\lgl\\erp\\controller\\basic\\";
//
//    private static final String projectPath = basePath + "common";
//    private static final String mapperPath = projectPath + "\\src\\main\\java\\com\\lgl\\db\\mapper\\basic\\";
//    private static final String mapperXmlPath = projectPath + "\\src\\main\\resources\\com\\lgl\\db\\mapper\\basic\\";

    private static final boolean view = true;

    // "order_instant_scan", "order_instant_code", "order_instant_code_log", "basic_instant_warning", "order_instant_trace",
    // "basic_instant_fee", "basic_instant_fee_ext", "basic_instant_fee_customer", "basic_file_export"
    // "basic_app_version", "record_notify_send"
    // "order_fuji", "order_panasonic", "order_labor"
    private static final String[] includeTables = {
        "order_labor",
    };

    public static void main(String[] args) {
        AutoGenerator autoGenerator = new AutoGenerator();

        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(projectPath + "/src/main/java");
        globalConfig.setAuthor("dongqilin");
        globalConfig.setOpen(false);
        globalConfig.setKotlin(true);
        globalConfig.setFileOverride(true);
        autoGenerator.setGlobalConfig(globalConfig);

        DataSourceConfig dataSourceConfig = dataSourceConfig();
        autoGenerator.setDataSource(dataSourceConfig);

        PackageConfig packageConfig = packageConfigBasic();
        autoGenerator.setPackageInfo(packageConfig);

        InjectionConfig injectionConfig = injectionConfig(packageConfig);
        autoGenerator.setCfg(injectionConfig);

        TemplateConfig templateConfig = templateConfig();
        autoGenerator.setTemplate(templateConfig);

        StrategyConfig strategyConfig = strategyConfig(packageConfig);
        autoGenerator.setStrategy(strategyConfig);

        autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());

        System.out.println("===================== MyBatis Plus Generator ==================");
        autoGenerator.execute();
        System.out.println("========== MyBatis Plus Generator Execute Complete ============");
    }

    private static DataSourceConfig dataSourceConfig() {
        // 数据源配置 需配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl(jdbcUrl);
        // dataSourceConfig.setSchemaName("public");
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSourceConfig.setUsername(username);
        dataSourceConfig.setPassword(password);
        return dataSourceConfig;
    }

    /**
     * 生成包配置
     */
    private static PackageConfig packageConfig() {
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(null);
        packageConfig.setParent(pkg);
        return packageConfig;
    }

    private static PackageConfig packageConfigBasic() {
        PackageConfig packageConfig = new PackageConfig();

        //如果需要手动输入模块名
        //packageConfig.setModuleName(scanner("模块名"));
        packageConfig.setModuleName(null);
        packageConfig.setParent(null);
        packageConfig.setController(pkgController);
        packageConfig.setMapper(pkgMapper);
        packageConfig.setEntity(pkg + ".bean.entity");
        packageConfig.setService(pkg + serviceInterfacePkg);
        packageConfig.setServiceImpl(pkg + serviceImplPkg);
        return packageConfig;
    }

    private static InjectionConfig injectionConfig(PackageConfig packageConfig) {
        // 自定义配置
        InjectionConfig injectionConfig = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();

        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(controller) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名
                return controllerPath + tableInfo.getEntityName() + "Controller.kt";
            }
        });
        focList.add(new FileOutConfig(mapper) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return mapperPath + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_KOTLIN;
            }
        });
        focList.add(new FileOutConfig(xml) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return mapperXmlPath + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        if (view) {
            focList.add(new FileOutConfig(viewList) {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    return viewPath + tableInfo.getControllerPath() + "/list.ftl";
                }
            });
            focList.add(new FileOutConfig(viewEdit) {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    return viewPath + tableInfo.getControllerPath() + "/edit.ftl";
                }
            });
            focList.add(new FileOutConfig(viewDetail) {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    return viewPath + tableInfo.getControllerPath() + "/detail.ftl";
                }
            });
        }

        injectionConfig.setFileOutConfigList(focList);
        return injectionConfig;
    }

    private static TemplateConfig templateConfig() {

        // 配置模板
        TemplateConfig config = new TemplateConfig();

        // 配置自定义输出模板
        //指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        config.setEntityKt(entityKt);
        config.setService(service);
        config.setServiceImpl(serviceImpl);
        config.setMapper("");
        config.setController("");
        config.setXml("");
        return config;
    }

    private static StrategyConfig strategyConfig(PackageConfig packageConfig) {
        // 策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setSuperEntityClass(BaseEntity.class);
        strategyConfig.setEntityLombokModel(true);
        strategyConfig.setSuperControllerClass(BaseController.class);
        strategyConfig.setRestControllerStyle(false);
        strategyConfig.setSuperServiceClass(IBaseService.class);
        strategyConfig.setSuperServiceImplClass(BaseServiceImpl.class);

        // 如果 setInclude() 不加参数, 会自定查找所有表
        // 如需要制定单个表, 需填写参数如: strategyConfig.setInclude("user_info);
        strategyConfig.setInclude(includeTables);
//        strategyConfig.setExclude(excludeTables);
        strategyConfig.setSuperEntityColumns("create_time", "update_time");
        strategyConfig.setControllerMappingHyphenStyle(true);

        strategyConfig.setEntityColumnConstant(true);

        //自动将数据库中表名为 user_info 格式的专为 UserInfo 命名
        strategyConfig.setTablePrefix(packageConfig.getModuleName() + "_");
        return strategyConfig;
    }

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + "：");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    private static void delete(File file) {
        File[] listFiles = file.listFiles();
        if (listFiles != null) {
            for (File f : listFiles) {
                if (f.isDirectory()) {
                    delete(f);
                } else {
                    f.delete();
                }
            }
        }
        file.delete();
    }
}
